////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "ConvexHullCreatorCanvas.hpp"

#include "../Form/ConvexHullCreatorDialog.h"

////////////////////////////////////////////////////////////
/// Construct the ConvexHullCreatorCanvas
////////////////////////////////////////////////////////////
ConvexHullCreatorCanvas::ConvexHullCreatorCanvas(wxWindow*        Parent,
                                                wxWindowID      Id,
                                                const wxPoint&  Position, 
                                                const wxSize&   Size, 
                                                long            Style) :
    wxSFMLCanvas(Parent, Id, Position, Size, Style),
    m_vertexArray(sf::LinesStrip, 3),
    m_iNumVertexSelected(-1),
    m_pPlaceableDragged(NULL),
    m_verticesPlaceable(3)
{
    // Connect Events
    this->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(ConvexHullCreatorCanvas::OnMouseLeftDown));
    this->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(ConvexHullCreatorCanvas::OnMouseLeftUp));
    this->Connect(wxEVT_MOTION, wxMouseEventHandler(ConvexHullCreatorCanvas::OnMouseMove));
}
    
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
ConvexHullCreatorCanvas::~ConvexHullCreatorCanvas() {
}

////////////////////////////////////////////////////////////
/// Update a vertex position
////////////////////////////////////////////////////////////
void ConvexHullCreatorCanvas::UpdateVertexPosition( unsigned _numVertex, float _x, float _y ) {
    if ( _numVertex < m_vertexArray.getVertexCount() ) {
        m_vertexArray[_numVertex].position.x = _x;
        m_vertexArray[_numVertex].position.y = _y;

        m_verticesPlaceable[_numVertex].setPosition( _x, _y );
    }
}
    
////////////////////////////////////////////////////////////
/// Resize the vertex array
////////////////////////////////////////////////////////////
void ConvexHullCreatorCanvas::Resize( int _numVertices ) {
    if ( _numVertices >= 3 ) {
        m_vertexArray.resize( _numVertices );
        m_verticesPlaceable.resize( _numVertices );
    }
}

////////////////////////////////////////////////////////////
/// Notification for the derived class that moment is good
/// for doing its update and drawing stuff
////////////////////////////////////////////////////////////
void ConvexHullCreatorCanvas::OnUpdate() {
    // On efface la vue
    clear();

    draw(m_vertexArray);

    // Draw a line between the last vertex and the first one
    sf::Vertex line[2] = {
        m_vertexArray[ m_vertexArray.getVertexCount() - 1 ],
        m_vertexArray[0]
    };
    draw(line, 2, sf::Lines);

    for (unsigned i = 0; i < m_verticesPlaceable.size(); ++i) {
        draw(m_verticesPlaceable[i]);
    }
}

////////////////////////////////////////////////////////////
/// Events
////////////////////////////////////////////////////////////
void ConvexHullCreatorCanvas::OnMouseLeftDown( wxMouseEvent& event ) {
    sf::Vector2f mousePosView( GetMousePosInViewSpace( event.GetPosition() ) );
    for (unsigned i = 0; i < m_verticesPlaceable.size(); ++i) {
        if ( SmegPlaceable::eDrag_None != m_verticesPlaceable[i].BeginDragSelection( mousePosView ) ){
            m_pPlaceableDragged = &m_verticesPlaceable[i];
            m_iNumVertexSelected = i;
            return;
        }
    }
}

void ConvexHullCreatorCanvas::OnMouseLeftUp( wxMouseEvent& event ) {
    if ( m_pPlaceableDragged ) {
        m_pPlaceableDragged->StopDragSelection();
        m_pPlaceableDragged = NULL;
        m_iNumVertexSelected = -1;
    }
}

void ConvexHullCreatorCanvas::OnMouseMove( wxMouseEvent& event ) {
    sf::Vector2f mousePosView( GetMousePosInViewSpace( event.GetPosition() ) );
    SmegPlaceable::eDragEnum dragMode = SmegPlaceable::eDrag_None;
    if ( event.LeftIsDown() && m_pPlaceableDragged ) {
        for (unsigned i = 0; i < m_verticesPlaceable.size(); ++i) {
            m_verticesPlaceable[i].ResetSelection();
        }

        m_pPlaceableDragged->DragSelection( mousePosView );

        m_vertexArray[m_iNumVertexSelected].position = m_pPlaceableDragged->getPosition();
        ((ConvexHullCreatorDialog*)GetParent())->OnVertexMoved( m_iNumVertexSelected, m_vertexArray[m_iNumVertexSelected].position.x, m_vertexArray[m_iNumVertexSelected].position.y );
    } else {
        for (unsigned i = 0; i < m_verticesPlaceable.size(); ++i) {
            if ( SmegPlaceable::eDrag_None == dragMode ) {
                dragMode = m_verticesPlaceable[i].SetSelection( mousePosView );
            } else {
                m_verticesPlaceable[i].ResetSelection();
            }
        }
    }
}
